<?php
/**
 * Since the array is not mutable, it should use an internal 
 * index over the number of elements for the previous/next 
 * validation.
 */
class ArrayIterator2 implements Iterator {
  public  $array;
  private $delm = ',';
  private $map = array(
      'emp_code'=>0
    , 'date'=>1
    , 'time'=>2
    , 'fn'=>3
  );
  public $fn_map = array(
       'out-of-calc' => array( 'in'=>'IN' , 'out'=>'OUT','max_period'=> 28800)
       //'IN' => array( 'max_period'=> 28800)
     //, 'OUT' => array( 'max_period'=> 28800)
     , 'leaves' => array(
          'buz' => array('in'=>'BUZIN' , 'out'=>'BUZOUT' ,'max_period'=> 10800)
         ,'smoke' => array('in'=>'SMIN' , 'out'=>'SMOUT' ,'max_period'=> 300)
     )
  );
  public function __construct($array ,$init_data = false , $fn_map = null) {
    if ( !is_array($array)) {
        throw new IllegalArgumentException( 'argument 0 is not an array' );
    }
    if(null !== $fn_map){
        $this->fn_map = $fn_map;
    }
    if($init_data){
        $this->init_data($array);
    }else{
        $this->array = $array;
    }
    //$this->array = $array;
    $this->rewind();
  }
  public function init_data($arr) {
    if(!is_array($arr)){
      throw new Exception('arary should be passed to init_data');
    }
    $this->array = array();
    $i = -1;
    foreach( $arr as $v ){
        if(!trim($v))continue;
        //$this->array[$k] = trim($v);
        $exp = explode( $this->delm , trim($v) );
        
        if(is_array($exp) && count($exp) > 0){
            $k = ++$i;
            foreach($this->map as $map_name => $exp_key){
                $this->array[$k][$map_name] = trim($exp[$exp_key]);
            }
            $this->array[$k]['datetime'] = calculate_date($exp[$this->map['date']] , $exp[$this->map['time']]);
            $this->array[$k]['timestamp'] = calculate_timestamp($exp[$this->map['date']] , $exp[$this->map['time']]);
        }
    }
  }
  public function valid() {
    return current($this->array) !== false;
    // that's the bad method (should use arrays_keys, + index)
  }
  public function key() {
     return key($this->array);
  }
  public function current() {
    return current($this->array);
  }
  public function next() {
    if ( $this->valid()) 
    next($this->array);
  }
  public function previous()  {
    // fails if current() = first item of array
    previous($this->array);
  }
  public function rewind() {
     reset($this->array);
  }
  public function print_r() {
     echo "<pre>";print_r($this->array);
  }
  
  /******************************/
  function count(){
    return count($this->array);
  }
  function get_item( $map_key=null , $k = null ){
    if( $k === null ){
        $item = $this->current();        
    } else {
        $item = $this->array[$k];
    }
    if(null === $map_key){
        //var_dump($k);exit;
        //var_dump($item);exit;
        return empty ($item) ?  null : $item;
    }else{
        return empty ($item[$map_key]) ?  null : $item[$map_key];
    }
  }
  function insert_in_place( $k , $item){
    if(!isset($this->array[$k])){
        $this->array[$k] = $item;
    }else{
        $count = count($this->array);
        for( $i = $count-1 ; $i > $k-1 ; $i-- ){
            $this->array[$i+1] = $this->array[$i];
        }
        $this->array[$k] = $item;
    }
  }
  function search( $map_key  , $value , $start_from = 0 , $is_reversed = false){
    if( ! $is_reversed){
        for( $i = $start_from ; $i < $this->count(); $i++ ){
            if( $this->array[$i][$map_key] == $value ){
                return $i;
            }
        }
    }else{
        for( $i = $start_from ; $i >= 0 ; $i-- ){
            if( $this->array[$i][$map_key] == $value ){
                return $i;
            }
        }
    }
    return -1;
  }
/**
 *
 * @return ArrayIterator2
 */
  function search_range( $map_key  , $value_from , $value_to , $start_from = 0 , $is_reversed = false){
        $output = array();
      if( ! $is_reversed){
        for( $i = $start_from ; $i < $this->count(); $i++ ){
            if( $this->array[$i][$map_key] >= $value_from  &&  $value_to > $this->array[$i][$map_key] ){
                $output[] = $this->get_item(null ,$i);
            }
        }
    }else{
        for( $i = $this->count() -1 ; $i > $start_from - 1 ; $i-- ){
            if( $this->array[$i][$map_key] >= $value_from  &&  $value_to > $this->array[$i][$map_key] ){
                $output[] = $this->get_item(null ,$i);
            }
        }
    }
    return count($output) > 0 ? new ArrayIterator2($output,0,$this->fn_map) : null;
    //return  null;
  }
  function search_array( $map_key  , $values_arr , $start_from = 0 , $is_reversed = false){
        $output = array();
      if( ! $is_reversed){
        for( $i = $start_from ; $i < $this->count(); $i++ ){
            if( in_array( $this->array[$i][$map_key]  ,$values_arr )  ) {
                $output[] = $this->get_item(null ,$i);
            }
        }
    }else{
        for( $i = $this->count() -1 ; $i > $start_from - 1 ; $i-- ){
            if( in_array( $this->array[$i][$map_key] ,$values_arr )  ) {
                $output[] = $this->get_item(null ,$i);
            }
        }
    }
    return count($output) > 0 ? new ArrayIterator2($output,0,$this->fn_map) : null;
    //return  null;
  }
  function add( $map_key  , $value , $place = false){
    if(!$place){
        $this->array[ $this->last_index() + 1 ][$map_key] = $value ;
    }else{
        $this->array[$place][$map_key] = $value ;
    }
    return $this->last_index();
  }
  function last_index( ){
    $index = $this->count();
    return $index < 0 ? 0 : $index;
  }

  function get_option( $map_key , $option , $default = NULL){
    if(isset($this->fn_map[$map_key][$option])){
        return $this->fn_map[$map_key][$option];
    }else{
        return $default;
    }

  }

  function get_option_namspace( $namespace , $option , $default = NULL){
    $option_array = $this->fn_map;
    if(strpos($namespace, '/')!==false){
        $exp_namespace = explode('/', $namespace);
        foreach ($exp_namespace as $sub_name){
            if(isset($option_array[$sub_name])){
                $option_array = $option_array[$sub_name];
            }
        }
    }else{
        $option_array = $option_array[$namespace];
    }

    if(isset($option_array[$option])){
        return $option_array[$option];
    }else{
        return $default;
    }

  }
  
}





